<template>
  <div id="upload-container">
    <el-upload
      title="点击上传文件"
      :action="ossHost"
      :data="ossData"
      list-type="picture-card"
      :on-preview="handlePictureCardPreview"
      :on-remove="handleRemove"
      :on-success="handleSuccess"
      :before-upload="beforeUpload">
      <i class="el-icon-plus"></i>
    </el-upload>
    <el-dialog :visible.sync="dialogVisible">
      <img width="100%" :src="dialogImageUrl" alt="">
    </el-dialog>
  </div>
</template>
<script>
  import {policy} from '@/api/upload'
  // 导入uuid库
  import uuidv4 from 'uuid/v4'

  export default {
    name: 'upload',
    data() {
      return {
        dialogImageUrl: '',
        dialogVisible: false,
        ossHost: '',
        ossData: {}
      }
    },
    created() {
    },
    methods: {
      handleSuccess(response, file, fileList) {
        console.log(this.ossData.key)
        // 将文件名保存到数据库
      },
      handleRemove(file, fileList) {
        console.log(file, fileList);
      },
      handlePictureCardPreview(file) {
        this.dialogImageUrl = file.url;
        this.dialogVisible = true;
      },
      beforeUpload(file) {
        // element ui upload需要一个promise对象
        return new Promise(resolve => {
          return this.getSign().then(data => {
            const suffix = file.name.substring(file.name.lastIndexOf("."))
            this.ossHost = data.host
            // 注意参数的大小写，oss文档就是这样定义的
            // 跟后端返回的变量名不一样，所以只能手动赋值
            this.ossData = {
              key: data.dir + uuidv4() + suffix,
              policy: data.policy,
              OSSAccessKeyId: data.accessKeyId,
              success_action_status: '200', //让服务端返回200，不设置则默认返回204。
              callback: data.callbackBody,
              signature: data.signature,
              expire: data.expire
            }
            resolve(true)
          })
        })
      },
      getSign() {
        // 因为获取签名的方法是异步的，所以通过promise对象执行签名过期判断
        // 确保异步方法执行完成后再执行then中的逻辑，否则可能获取不到值
        return new Promise(resolve => {
          // 判断签名有没有过期，过期了就重新获取签名
          let sign = JSON.parse(sessionStorage.getItem("hncc-oss-sign"));
          let timestamp = Date.parse(new Date()) / 1000;
          if (sign && sign.expire - 3 > timestamp) {
            resolve(sign);
          } else {
            // 重新获取签名并保存
            policy().then(response => {
              sessionStorage.setItem("hncc-oss-sign", JSON.stringify(response.data));
              resolve(response.data);
            });
          }
        })
      }
    }
  }
</script>
